{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9ed3e1d8-4a57-4353-a615-2477b983cc34",
   "metadata": {},
   "source": [
    "### 导入依赖库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c5491e76-63b9-454d-9a44-719e419c9585",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.chat_models import ChatZhipuAI\n",
    "from langchain_core.tools import tool\n",
    "from datetime import datetime\n",
    "import pytz\n",
    "from langchain.agents import initialize_agent, AgentType\n",
    "# from langchain_core.agents import AgentAction, AgentFinish"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1874e6a1-8bb5-426a-9ef1-c1ebc49f5524",
   "metadata": {},
   "source": [
    "### 配置API密钥"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "0d5592d7-8128-42dd-9eba-a0906a7ed8f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"ZHIPUAI_API_KEY\"] = \"你的api key\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8640ebc-1b66-4ae8-b663-8c54f4fe7eda",
   "metadata": {},
   "source": [
    "### 初始化GLM-4-Flash模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c1e4e3d3-53bc-475f-a67d-22e364636de7",
   "metadata": {},
   "outputs": [],
   "source": [
    "chat = ChatZhipuAI(\n",
    "    model=\"glm-4-flash\",\n",
    "    temperature=0.5,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5597713-679e-4852-bc85-d9ee88569fd3",
   "metadata": {},
   "source": [
    "### 工具创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "ce0bc16a-d85a-4bb5-a287-d5f897886ba8",
   "metadata": {},
   "outputs": [],
   "source": [
    "@tool\n",
    "def get_current_time(timezone: str = \"America/New_York\") -> str:\n",
    "    \"\"\"获取指定时区的当前时间（默认北京时间）\"\"\"\n",
    "    now = datetime.now().astimezone(pytz.timezone(timezone))\n",
    "    return f\"当前时间：{now.strftime('%Y-%m-%d %H:%M:%S %Z')}\"\n",
    "\n",
    "@tool\n",
    "def currency_converter(amount: float, from_cur: str, to_cur: str) -> str:\n",
    "    \"\"\"货币汇率转换（示例工具，实际需接入API）\"\"\"\n",
    "    rates = {\"USD-CNY\": 7.25, \"EUR-CNY\": 7.88}  # 模拟汇率数据\n",
    "    key = f\"{from_cur}-{to_cur}\"\n",
    "    return f\"{amount} {from_cur} = {amount * rates.get(key, 1)} {to_cur}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56729b22-9085-4c48-b4df-7fb9f37b0334",
   "metadata": {},
   "source": [
    "### 智能体创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "eb52e94c-2439-418c-9f0d-77cf5e035cee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AgentExecutor(verbose=True, tags=['structured-chat-zero-shot-react-description'], agent=StructuredChatAgent(llm_chain=LLMChain(verbose=False, prompt=ChatPromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={}, partial_variables={}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='Respond to the human as helpfully and accurately as possible. You have access to the following tools:\\n\\nget_current_time: 获取指定时区的当前时间（默认北京时间）, args: {{\\'timezone\\': {{\\'default\\': \\'America/New_York\\', \\'title\\': \\'Timezone\\', \\'type\\': \\'string\\'}}}}\\ncurrency_converter: 货币汇率转换（示例工具，实际需接入API）, args: {{\\'amount\\': {{\\'title\\': \\'Amount\\', \\'type\\': \\'number\\'}}, \\'from_cur\\': {{\\'title\\': \\'From Cur\\', \\'type\\': \\'string\\'}}, \\'to_cur\\': {{\\'title\\': \\'To Cur\\', \\'type\\': \\'string\\'}}}}\\n\\nUse a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).\\n\\nValid \"action\" values: \"Final Answer\" or get_current_time, currency_converter\\n\\nProvide only ONE action per $JSON_BLOB, as shown:\\n\\n```\\n{{\\n  \"action\": $TOOL_NAME,\\n  \"action_input\": $INPUT\\n}}\\n```\\n\\nFollow this format:\\n\\nQuestion: input question to answer\\nThought: consider previous and subsequent steps\\nAction:\\n```\\n$JSON_BLOB\\n```\\nObservation: action result\\n... (repeat Thought/Action/Observation N times)\\nThought: I know what to respond\\nAction:\\n```\\n{{\\n  \"action\": \"Final Answer\",\\n  \"action_input\": \"Final response to human\"\\n}}\\n```\\n\\nBegin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\\nThought:'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={}, partial_variables={}, template='{input}\\n\\n{agent_scratchpad}'), additional_kwargs={})]), llm=ChatZhipuAI(zhipuai_api_key='6be9c791438e4942bc15689ea99bd053.Dd9c9aHWYy90FrOk', zhipuai_api_base='https://open.bigmodel.cn/api/paas/v4/chat/completions', model_name='glm-4-flash', temperature=0.5), output_parser=StrOutputParser(), llm_kwargs={}), output_parser=StructuredChatOutputParserWithRetries(base_parser=StructuredChatOutputParser(), output_fixing_parser=OutputFixingParser(parser=StructuredChatOutputParser(), retry_chain=PromptTemplate(input_variables=['completion', 'error', 'instructions'], input_types={}, partial_variables={}, template='Instructions:\\n--------------\\n{instructions}\\n--------------\\nCompletion:\\n--------------\\n{completion}\\n--------------\\n\\nAbove, the Completion did not satisfy the constraints given in the Instructions.\\nError:\\n--------------\\n{error}\\n--------------\\n\\nPlease try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:')\n",
       "| ChatZhipuAI(zhipuai_api_key='6be9c791438e4942bc15689ea99bd053.Dd9c9aHWYy90FrOk', zhipuai_api_base='https://open.bigmodel.cn/api/paas/v4/chat/completions', model_name='glm-4-flash', temperature=0.5)\n",
       "| StrOutputParser())), allowed_tools=['get_current_time', 'currency_converter']), tools=[StructuredTool(name='get_current_time', description='获取指定时区的当前时间（默认北京时间）', args_schema=<class 'langchain_core.utils.pydantic.get_current_time'>, func=<function get_current_time at 0x000001D457A3C5E0>), StructuredTool(name='currency_converter', description='货币汇率转换（示例工具，实际需接入API）', args_schema=<class 'langchain_core.utils.pydantic.currency_converter'>, func=<function currency_converter at 0x000001D457A3C9A0>)])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "# 工具列表\n",
    "tools = [get_current_time, currency_converter]\n",
    "\n",
    "# 初始化代理\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    chat,  # GLM-4-Flash模型\n",
    "    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,  # 结构化决策\n",
    "    verbose=True  # 显示详细思考过程\n",
    ")\n",
    "\n",
    "agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "67616f9b-3ae5-40e9-a72d-efdeed37b9c1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: I need to find the current time in New York and then convert 100 USD to CNY.\n",
      "Action:\n",
      "```json\n",
      "{\n",
      "  \"action\": \"get_current_time\",\n",
      "  \"action_input\": {\"timezone\": \"America/New_York\"}\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m当前时间：2025-04-05 08:40:47 EDT\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3mAction:\n",
      "```json\n",
      "{\n",
      "  \"action\": \"currency_converter\",\n",
      "  \"action_input\": {\n",
      "    \"amount\": 100,\n",
      "    \"from_cur\": \"USD\",\n",
      "    \"to_cur\": \"CNY\"\n",
      "  }\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[33;1m\u001b[1;3m100.0 USD = 725.0 CNY\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3mAction:\n",
      "```json\n",
      "{\n",
      "  \"action\": \"Final Answer\",\n",
      "  \"action_input\": \"当前纽约时间是2025-04-05 08:40:47 EDT，100美元对应725人民币。\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "当前纽约时间是2025-04-05 08:40:47 EDT，100美元对应725人民币。\n"
     ]
    }
   ],
   "source": [
    "# 执行查询\n",
    "response = agent.invoke(\"现在纽约时间几点？换算100美元对应多少人民币？\")\n",
    "print(response[\"output\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bc0d37e9-6037-4c97-9180-90b781e2d8c2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
